/*

This file is part of Rooms3D.

Copyright (C) 2008 Pixecur Technologies Incorporated (Esotera).
Visit Esotera at http://www.esoteras3.com
 
Rooms3D is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
 
Rooms3D is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with Rooms3D; see the file COPYING.  If not, write to 
Pixecur Technologies, 213-31 Peet Street, St. John's, NL, A1B 3W8. 
 
Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
 
*/

package com.datasentinel.j3d.controls;

import java.awt.Font;
import java.awt.SystemColor;

import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Material;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Vector3d;

import com.datasentinel.j3d.controls.geom.ButtonBox;
import com.datasentinel.j3d.utils.geometry.MutableText2D;


public class J3DButtonUI extends J3DComponentUI
{

	private Dimension3f defaultSize;

	private Font textFont;

//	private Point3f defaultTextOffset;

	/**
	 * Appearance properties
	 */

	private Appearance bodyAppearance;

	/**
	 * -- Branch elements --
	 * 
	 * Internal primitive disposition
	 */

	private Transform3D translateTextT3D;
	private Transform3D translateBodyT3D;
	private Transform3D scaleBodyT3D;
	private Transform3D rotateBodyT3D;
	private Transform3D pressButtonT3D;

//	private TransformGroup rotateTextTrnsGrp;
	private TransformGroup translateTextTrnsGrp;
	private TransformGroup rotateBodyTrnsGrp;
	private TransformGroup translateBodyTrnsGrp;
	private TransformGroup scaleBodyTrnsGrp;
	private TransformGroup pressButtonTrnsGrp;
	
//	/**
//	 * Container
//	 */
//	private BranchGroup buttonBrnchGrp;

	/**
	 * Visual primitives
	 */
	private ButtonBox bodyBox;
	private MutableText2D buttonText2D;
	
	
	
	public J3DButtonUI()
	{
	}
	

	@Override
	protected void initializeComponentParts()
	{
		initializeComponentVisualPropertiesDefaultValues();
		
//		buttonBrnchGrp = new BranchGroup();
		
		textFont = new Font(Font.SANS_SERIF, Font.BOLD, 85);

		buttonText2D = new MutableText2D("", new Color3f(SystemColor.controlText),
				textFont.getFontName(), textFont.getSize(), textFont.getStyle());
		
		initializeBodyBox();		
	}

	@Override
	protected void initializeComponentPartsLayout()
	{
		translateTextT3D = new Transform3D();
		translateBodyT3D = new Transform3D();
		scaleBodyT3D = new Transform3D();
		rotateBodyT3D = new Transform3D();
		pressButtonT3D = new Transform3D();
		
		initializeShapes3DLayout();
		
		translateTextTrnsGrp = new TransformGroup(translateTextT3D);
		translateTextTrnsGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//		translateTextTrnsGrp.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
//		translateTextTrnsGrp.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
		
		scaleBodyTrnsGrp = new TransformGroup(scaleBodyT3D);
		scaleBodyTrnsGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		scaleBodyTrnsGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

		rotateBodyTrnsGrp = new TransformGroup(rotateBodyT3D);
		translateBodyTrnsGrp = new TransformGroup(translateBodyT3D);
		pressButtonTrnsGrp = new TransformGroup(pressButtonT3D);
		pressButtonTrnsGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		pressButtonTrnsGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		
		
	}



	private void initializeShapes3DLayout()
	{
		scaleBodyT3D.setScale(defaultSize.getVector3d());
//		rotateBodyT3D.rotY(Math.PI/2);
//		bodyT3D.setScale(defaultSize.getVector3d());
//		rotateBodyT3D.rotX(Math.PI/8);
//		Transform3D rotAux = new Transform3D();
//		rotAux.rotY(Math.PI/6);
//		rotateBodyT3D.mul(rotAux);
//		 = new Transform3D();
//		
//		translateTextTrnsGrp.setTransform(translateTextT3D);
	}
	
	private void initializeBodyBox()
	{

		Material bodyMaterial;
		
		bodyMaterial = new Material();
//		bodyMaterial.setEmissiveColor(new Color3f(Color.GREEN));
		bodyMaterial.setLightingEnable(true);
		
		bodyAppearance = new Appearance();
		bodyAppearance.setMaterial(bodyMaterial);
//		PolygonAttributes polygonAttributes = new PolygonAttributes();
//		polygonAttributes.setPolygonMode(PolygonAttributes.POLYGON_LINE);
//		bodyAppearance.setPolygonAttributes(polygonAttributes);
		
		bodyBox = new ButtonBox();
		
		bodyBox.setAppearance(bodyAppearance);
		
		Material frontSideMaterial = new Material();
		frontSideMaterial.setEmissiveColor(new Color3f(SystemColor.control));
		Appearance frontSideAppearance = new Appearance();
		frontSideAppearance.setMaterial(frontSideMaterial);
		Shape3D frontSideS3D = bodyBox.getShape(ButtonBox.FRONT);
		frontSideS3D.setAppearance(frontSideAppearance);
		
		Material sideMaterial = new Material();
		sideMaterial.setEmissiveColor(new Color3f(SystemColor.controlShadow.brighter()));
		Appearance sideAppearance = new Appearance();
		sideAppearance.setMaterial(sideMaterial);
		Shape3D sideS3D = bodyBox.getShape(ButtonBox.TOP);
		sideS3D.setAppearance(sideAppearance);

		sideMaterial = new Material();
		sideMaterial.setEmissiveColor(new Color3f(SystemColor.controlShadow));
		sideAppearance = new Appearance();
		sideAppearance.setMaterial(sideMaterial);
		sideS3D = bodyBox.getShape(ButtonBox.RIGHT);
		sideS3D.setAppearance(sideAppearance);
	
		sideMaterial = new Material();
		sideMaterial.setEmissiveColor(new Color3f(SystemColor.controlDkShadow));
		sideAppearance = new Appearance();
		sideAppearance.setMaterial(sideMaterial);
		sideS3D = bodyBox.getShape(ButtonBox.LEFT);
		sideS3D.setAppearance(sideAppearance);

		sideMaterial = new Material();
		sideMaterial.setEmissiveColor(new Color3f(SystemColor.controlDkShadow.darker()));
		sideAppearance = new Appearance();
		sideAppearance.setMaterial(sideMaterial);
		sideS3D = bodyBox.getShape(ButtonBox.BOTTOM);
		sideS3D.setAppearance(sideAppearance);
		
	}
	
	
	private void initializeComponentVisualPropertiesDefaultValues()
	{
		/**
		 * Basically sets ratio between the sides of the button.
		 */
		defaultSize = new Dimension3f(1.0f, 0.3f, 1.0f);
	}
	
	/**
	 * Construction of the local branch of the Scene Graph
	 */
	protected void constructComponentGUIBranch()
	{
		/**
		 * >> Level 4
		 */
		scaleBodyTrnsGrp.addChild(bodyBox);
		translateTextTrnsGrp.addChild(buttonText2D);
		/**
		 * >> Level 3
		 */
		pressButtonTrnsGrp.addChild(scaleBodyTrnsGrp);
		pressButtonTrnsGrp.addChild(translateTextTrnsGrp);
		/**
		 * >> Level 2
		 */
		translateBodyTrnsGrp.addChild(pressButtonTrnsGrp);
		/**
		 * >> Level 1
		 */
		rotateBodyTrnsGrp.addChild(translateBodyTrnsGrp);
		/**
		 * >> Level 0
		 */
		baseBrnchGrp.addChild(rotateBodyTrnsGrp);
		
		baseBrnchGrp.compile();
	}


	
	public void render3DComponent(J3DComponent j3dComponent)
	{
		
		J3DButton j3dButton = (J3DButton)j3dComponent;
		
		ButtonModel3D model = j3dButton.getModel();
		
		String buttonText = buttonText2D.getString();
		if(buttonText == null || !buttonText.equals(model.getText()))	
		{
			buttonText2D.setString(model.getText());
			
			J3DUIHelper.prepareCenteredText2DTransform(j3dButton.getCanvas3D(), 
					textFont, buttonText2D, translateTextT3D, bodyBox.getHeight());
			translateTextTrnsGrp.setTransform(translateTextT3D);
//			adjustText2DPlacement(j3dButton);
		}
		
		if(model.isPressed())
		{
			pressButtonT3D.setIdentity();
			pressButtonT3D.setScale(new Vector3d(1.0, 1.0, bodyBox.getHeight() / 10.0f));
			pressButtonTrnsGrp.setTransform(pressButtonT3D);
		}
		else
		{
			pressButtonT3D.setIdentity();
			pressButtonTrnsGrp.setTransform(pressButtonT3D);
		}
	}
	
	public Dimension3f getDefaultSize()
	{
		return defaultSize;
	}
	
	public BranchGroup get3DComponent()
	{
		return baseBrnchGrp;
	}

}
